home *** CD-ROM | disk | FTP | other *** search
/ Revista CD Expert 8 / Revista CD Expert nº 08 CD1.iso / Utilitarios / Internet / WebExpress / wbx32.exe / MVFORMS.CGI < prev    next >
Encoding:
Text File  |  1998-01-01  |  16.5 KB  |  648 lines

  1. #!/usr/local/bin/perl
  2. #the perl path may need to be set if your web host is running Un*x
  3.  
  4. require 5.0;
  5.  
  6. #the path to the sendmail program will need to be set on Un*x systems
  7. $mail_program = "/usr/lib/sendmail -t";
  8.  
  9. #on NT the name of the smtp server must be set 
  10. $smtp_server = "smtp.surething.com";
  11.  
  12. use Env;
  13.  
  14. # turn off output buffering for AnaServe - effect unknown Patrick 10/21/98
  15. $| = 1;
  16.  
  17. ##########################################################################
  18. #
  19. #    MVForms.cgi - A form response script for use with WebExpress.
  20. #    Copyright 1997 MicroVision Development, Inc.
  21. #
  22. #    Version 3.00    Sep 29 1998
  23. #            3.01    Oct 22 1998 - Unix sendmail version had inverted to and from addresses.
  24. #                                - Removed all extraneous whitespace and reformated with
  25. #                                  spaces rather than tabs.
  26. #                                - Modified .thanks_url processing to allow it to be set to either
  27. #                                  a complete URL, or a file name relative to the directory
  28. #                                  containing the form page.
  29. #
  30. #    Special thanks to Selena Sol and Sanford Morton
  31. #    for examples and explanations. Thanks to William Mussatto
  32. #    for posting the sendmail.pl script on the Win32-Perl-Web list,
  33. #    and to C. Mallwitz for writing it.
  34. #
  35. #    Permission is granted to use, modify and distribute
  36. #    this script, so long as this copyright section is
  37. #    included intact.
  38. #
  39. #
  40. #    This script gives the option of using Un*x sendmail on systems that
  41. #    have it available. To use the perl sendmail that is built in
  42. #    access to an SMTP server is required.
  43. #
  44. ############################################################################
  45.  
  46. # Instructions page
  47. # Used if the page owner forgets to supply .email_target hidden tag
  48. #$instructions_url = "http://www.halcyon.com/sanford/cgi/web2mail/index.html";
  49.  
  50. #
  51. # Program Begins Here
  52. #
  53.  
  54. # parse the form data
  55. &ReadParse;
  56.  
  57.  
  58. #
  59. # Check required fields were filled by the user
  60. #
  61. if ($in{'.required'})
  62. {
  63.     &Compulsory;
  64. }
  65.  
  66. if ( ! $in{'.intro'} ) 
  67. {
  68.     &usage("the intro for the response (<I>.intro</I>)");
  69. }
  70.  
  71. #
  72. # set the current date
  73. #
  74. $current_date = &get_date; 
  75.  
  76. #
  77. # if it is a redirect menu, jump
  78. #
  79. if ( $in{'.form_type'} eq "jump" )
  80. {
  81.     &jump_url;
  82. }
  83.  
  84. #
  85. # Otherwise, send an email response 
  86. #
  87.  
  88. #
  89. # Check for required hidden fields
  90. #
  91. if ( !$in{'.email_dest'} ) 
  92. {
  93.     &usage("the email desitination field (<I>.email_dest</I>)");
  94. }
  95.  
  96. if ( ! $in{'.intro'} ) 
  97. {
  98.     &usage("the intro for the response (<I>.intro</I>)");
  99. }
  100.  
  101. if ( ! $in{'.subject'} ) 
  102. {
  103.     &usage("the subject for the response (<I>.subject</I>)");
  104. }
  105.  
  106. #
  107. # send the response
  108. #
  109. &send_response;
  110.  
  111. #
  112. # Redirect to acknowledgement page
  113. #
  114. &send_acknowledgement;
  115.  
  116. exit;
  117.  
  118. ######################################
  119. # Parse the cgi form data.
  120. # Adapted from cgi-lib.pl by S.E.Brenner@bioc.cam.ac.uk 
  121. # Copyright 1994 Steven E. Brenner 
  122. #
  123. sub ReadParse
  124. {
  125.     local (*in) = @_ if @_;
  126.  
  127.     if ( $ENV{'REQUEST_METHOD'} eq "GET" )
  128.     {
  129.         # replaced his MethGet function
  130.         ## don't accept GET, to make it a little harder to spoof the script
  131.         print "Content-type: text/html\n\n";
  132.         print "Sorry, this script only accepts METHOD=POST. ";
  133.         print "Use that inside your <FORM ...> tag";
  134.         exit;
  135.     }
  136.     elsif ($ENV{'REQUEST_METHOD'} eq "POST")
  137.     {
  138.         read(STDIN,$in,$ENV{'CONTENT_LENGTH'});
  139.     }
  140.     else
  141.     {
  142.         # Added for command line debugging
  143.         # Supply name/value form data as a command line argument
  144.         # Format: name1=value1\&name2=value2\&... (need to escape & for shell)
  145.         # Find the first argument that's not a switch (-)
  146.         $in = ( grep( !/^-/, @ARGV )) [0];
  147.         $in =~ s/\\&/&/g;
  148.     }
  149.     @in = split(/&/,$in);
  150.  
  151.     foreach $i (0 .. $#in)
  152.     {
  153.         # Convert plus's to spaces
  154.         $in[$i] =~ s/\+/ /g;
  155.  
  156.         # Split into key and value.
  157.         ($key, $val) = split(/=/,$in[$i],2); # splits on the first =.
  158.  
  159.         # Convert %XX from hex numbers to alphanumeric
  160.         $key =~ s/%(..)/pack("c",hex($1))/ge;
  161.         $val =~ s/%(..)/pack("c",hex($1))/ge;
  162.  
  163.         # Associate key and value
  164.         # \0 is the multiple separator
  165.         $in{$key} .= "\0" if (defined($in{$key}));
  166.         $in{$key} .= $val;
  167.    }
  168.    return length($in);
  169. }
  170.  
  171. ############################
  172. #
  173. # sub Compulsory
  174. #
  175. # Check that the fields in the form that are required to be
  176. # filled are filled. Compulsory fields are listed in the
  177. # .required hidden field, semi-colon separated.
  178.  
  179. sub Compulsory
  180. {
  181.     #split them out of the list in the value field
  182.     @required = split (/;/, $in{'.required'});
  183.  
  184.     #check that each required field name keys to data in the input hash
  185.     foreach $elem (@required)
  186.     {
  187.         foreach $key (keys %in)
  188.         {
  189.             next if ($key ne $elem);
  190.  
  191.             #the required field and the key match, so check that there is data
  192.             if (!$in{$elem})
  193.             {
  194.                 $printkey = $elem;
  195.                 $printkey =~ s/^..//;
  196.                 $error .= ("<li>The $printkey field must be filled.<p>\n");
  197.             }
  198.         }
  199.     }
  200.  
  201.     if ($error)
  202.     {
  203.         #kick them to a page telling them what was blank
  204.         #use back button to get back to the form.
  205.  
  206.         #******************** CUSTOMIZABLE TEXT ********************
  207.         $error_page  = "Content-type: text/html\n\n";
  208.         $error_page .= "<head><TITLE>Form Entries Incomplete or Invalid</TITLE></head>\n<body><p>\n";
  209.         $error_page .= "<hr>\n<H3>Form Entries Incomplete or Invalid</H3>\n";
  210.         $error_page .= "One or more problems exist with the data you have entered.<UL>\n";
  211.         $error_page .= $error;
  212.         $error_page .= "</UL>Please use the <I>Back</I> button on your web browser to problems.<P><HR></BODY></HTML>";
  213.  
  214.     print $error_page;
  215.     exit; 
  216.     }
  217. }
  218. ######################################
  219. # general usage routine
  220. #
  221. sub usage
  222. {
  223.     my ($usage_error) = @_;
  224.  
  225.     $usage_body  = "Content-type: text/html\n\n";
  226.     $usage_body .= "<H2> Form Processing Error </H2>";
  227.     $usage_body .= "<TITLE> Form Processing Error </TITLE>";
  228.     $usage_body .= "You have forgotten to include <B>$usage_error</B> in your form. ";
  229.     $usage_body .= "Please correct the problem in your form, and try again. ";
  230.     $usage_body .= "<P>The following fields were included in your form: <OL>";
  231.  
  232.     foreach (keys %in)
  233.     {
  234.         $usage_body .= "<LI>$_: $in{$_}\n";
  235.     }
  236.  
  237.     $usage_body .= "</OL>Press the <B>BACK</B> button to return to the submitting form.";
  238.  
  239.     print $usage_body;
  240.     exit;
  241. }
  242. ######################################
  243. sub get_date
  244. {
  245.     $current_century = 20;
  246.  
  247.     @days = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
  248.  
  249.     @months = ('January','February','March','April','May','June','July','August','September','October','November','December');
  250.  
  251.     ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  252.  
  253.     if ($hour < 10)
  254.     {
  255.         $hour = "0$hour";
  256.     }
  257.  
  258.     if ($min < 10)
  259.     {
  260.         $min = "0$min";
  261.     }
  262.  
  263.     if ($sec < 10)
  264.     {
  265.         $sec = "0$sec";
  266.     }
  267.  
  268.     $year = ($current_century-1) . "$year";
  269.     $date = "$days[$wday], $months[$mon] $mday, $year at $hour\:$min\:$sec";
  270.  
  271.     return $date;
  272. }
  273.  
  274. ######################################
  275. #    jump to URL destination
  276. #
  277. sub jump_url
  278. {
  279.     # look for destination field
  280.     foreach (keys %in)
  281.     {
  282.         next if /^\./;  # skip hidden form data in mail message
  283.  
  284.         if ( $_ eq "Destination" )
  285.         {
  286.             $dest = $in{$_};
  287.         }
  288.     }
  289.  
  290.     # could check destination here
  291.     print "Location: $dest\n\n";
  292.     exit;
  293. }
  294.  
  295. ######################################
  296. # send repsonse
  297. #
  298. sub send_response
  299. {
  300.     $email_body = $in{'.intro'} ? "$in{'.intro'}\n\n" : "The following data has been submitted:\n\n";
  301.  
  302.     # added functionality to allow users to specify fields and order using the
  303.     # .remove_indexing key and the .response_order hidden field.
  304.     if (!$in{'.remove_indexing'} and $in{'.response_order'})
  305.     {
  306.         # split them out of the list in the value field
  307.         @resp_ordr = split (/;/, $in{'.response_order'});
  308.  
  309.         foreach    $ro_elem (@resp_ordr)
  310.         {
  311.             # format the text and add it to the mail message
  312.             $form_name = &format_text_field("$ro_elem:");
  313.  
  314.             $item = "$form_name $in{$ro_elem}";
  315.  
  316.             # if multiple values, indent them on new lines
  317.             $item =~ s/\0/"\n\t".(" "x(2+length($_)))/ge;
  318.  
  319.             $email_body .= "\t $item \n";
  320.  
  321.             # grab the mail address and save it
  322.             if ($ro_elem =~ /.*(email).*|.*(e-mail).*/i)
  323.             {
  324.                 $client_email = $in{$ro_elem};
  325.             }
  326.         }
  327.     }
  328.     else
  329.     {
  330.         foreach (sort keys %in)
  331.         {
  332.             # skip fields beginning with a period (hidden fields)
  333.             next if /^\./;
  334.  
  335.             # save client email for return address
  336.             if ( $_ eq "zzClientEmail" )
  337.             {
  338.                 $client_email = $in{$_};
  339.             } 
  340.  
  341.             # don't list the send and clear buttons
  342.             if ( $_ eq "xxSend" )
  343.             {
  344.                 next;
  345.             }
  346.  
  347.             if ( $_ eq "xxClear" )
  348.             {
  349.                 next;
  350.             }
  351.  
  352.             $form_name = &format_text_field("$_:");
  353.             $item = "$form_name $in{$_}";
  354.  
  355.             if ( $in{'.remove_indexing'} )
  356.             {
  357.                 $item =~ s/^..//;
  358.             }
  359.  
  360.             # if multiple values, indent them on new lines
  361.             $item =~ s/\0/"\n\t".(" "x(2+length($_)))/ge;
  362.  
  363.             $email_body .= "\t $item \n";
  364.         }
  365.         $flag = "did case two<br>\n";
  366.     }
  367.  
  368.     #******************** CUSTOMIZABLE TEXT ********************
  369.     $email_body .= "<br>\nSubmitted on: $current_date";
  370.     $email_body .= "<br>\nForm page: $ENV{HTTP_REFERER}";
  371.     $email_body .= "<br>\nUser address: $ENV{REMOTE_ADDR}";
  372.     $email_body .= "<br>\nUser host: $ENV{REMOTE_HOST}";
  373.  
  374.     $in{'.email_dest'} =~ s/,.*//;
  375.  
  376.     # to and from addresses are flipped between the NT and Unix versions
  377.     # here Patrick 10/21/98
  378.     if ($ENV{OS} eq "Windows_NT")
  379.     {
  380.         &sendmail($client_email,$client_email,$in{'.email_dest'},$smtp_server,$in{'.subject'},$email_body);
  381.     }
  382.     else
  383.     {
  384.         &send_mail ($client_email,$in{'.email_dest'},$in{'.subject'},$email_body);
  385.     }
  386. }
  387.  
  388. #####################################
  389. sub format_text_field
  390. {
  391.     my ($value) = @_;
  392.  
  393.     return($value . substr((" " x 25), length($value)));
  394. }
  395.  
  396. #---------------------------------------------------------------------------
  397. # sub sendmail()
  398. # Modified 10-20-1997 to not send blank fields.
  399. #
  400. # send/fake email around the world ...
  401. #
  402. # Version : 1.21
  403. # Environment: Hip Perl Build 105 NT 3.51 Server SP4
  404. # Environment: Hip Perl Build 110 NT 4.00
  405. #
  406. # arguments:
  407. #
  408. # $from email address of sender
  409. # $reply email address for replying mails
  410. # $to email address of reciever
  411. # (multiple recievers can be given separated with space)
  412. # $smtp name of smtp server (name or IP)
  413. # $subject subject line
  414. # $message (multiline) message
  415. #
  416. # return codes:
  417. #
  418. # 1 success
  419. # -1 $smtphost unknown
  420. # -2 socket() failed
  421. # -3 connect() failed
  422. # -4 service not available
  423. # -5 unspecified communication error
  424. # -6 local user $to unknown on host $smtp
  425. # -7 transmission of message failed
  426. # -8 argument $to empty
  427. #
  428. # usage examples:
  429. #
  430. # print
  431. # sendmail("Alice <alice\@company.com>",
  432. # "alice\@company.com",
  433. # "joe\@agency.com charlie\@agency.com",
  434. # $smtp, $subject, $message );
  435. #
  436.  
  437.  
  438. # or
  439. #
  440. # print
  441. # sendmail($from, $reply, $to, $smtp, $subject, $message );
  442. #
  443. # (sub changes $_)
  444. #
  445. #------------------------------------------------------------1;
  446.  
  447. use Socket;
  448. use IO::Handle;
  449.  
  450. sub sendmail
  451. {
  452.     ($from, $reply, $to, $smtp, $subject, $message) = @_;
  453.  
  454.     $fromaddr = $from;
  455.     $replyaddr = $reply;
  456.  
  457.     $to =~ s/[ \t]+/, /g; # pack spaces and add comma
  458.     $fromaddr =~ s/.*<([^\s]*?)>/$1/; # get from email address
  459.     $replyaddr =~ s/.*<([^\s]*?)>/$1/; # get reply email address
  460.     $replyaddr =~ s/^([^\s]+).*/$1/; # use first address
  461.     $message =~ s/^\./\.\./gm; # handle . as first character
  462.     $message =~ s/\r\n/\n/g; # handle line ending
  463.     $message =~ s/\n/\r\n/g;
  464.     $smtp =~ s/^\s+//g; # remove spaces around $smtp
  465.     $smtp =~ s/\s+$//g;
  466.  
  467.     if (!$to)
  468.     {
  469.     return(-8);
  470.     }
  471.  
  472.     $proto = (getprotobyname('tcp'))[2];
  473.     $port = (getservbyname('smtp', 'tcp'))[2];
  474.  
  475.     $smtpaddr = ($smtp =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) ? pack('C4',$1,$2,$3,$4) : (gethostbyname($smtp))[4];
  476.  
  477.     if (!defined($smtpaddr))
  478.     {
  479.         return(-1);
  480.     }
  481.  
  482.     if (!socket(S, AF_INET, SOCK_STREAM, $proto))
  483.     {
  484.         return(-2);
  485.     }
  486.  
  487.     if (!connect(S, pack('Sna4x8', AF_INET, $port, $smtpaddr)))
  488.     {
  489.         return(-3);
  490.     }
  491.  
  492.     S->autoflush(1);
  493.  
  494.     $_ = <S>;
  495.     if (/^[45]/)
  496.     {
  497.         close(S);
  498.         return(-4);
  499.     }
  500.  
  501.     print S "helo localhost\r\n";
  502.     $_ = <S>;
  503.     if (/^[45]/)
  504.     {
  505.         close(S);
  506.         return(-5);
  507.     }
  508.  
  509.     print S "mail from: <$fromaddr>\r\n";
  510.     $_ = <S>;
  511.     if (/^[45]/)
  512.     {
  513.         close(S);
  514.         return(-5);
  515.     }
  516.  
  517.     foreach (split(/, /, $to))
  518.     {
  519.         print S "rcpt to: <$_>\r\n";
  520.         $_ = <S>;
  521.         if (/^[45]/){
  522.         close(S);
  523.         return(-6);
  524.         }
  525.     }
  526.  
  527.     print S "data\r\n";
  528.     $_ = <S>;
  529.     if (/^[45]/)
  530.     {
  531.         close S;
  532.         return(-5);
  533.     }
  534.  
  535.     print S "To: $to\r\n";
  536.     print S "From: $from\r\n";
  537.     print S "Reply-to: $replyaddr\r\n" if $replyaddr;
  538.     print S "X-Mailer: Perl Sendmail Version 1.21\r\n";
  539.     print S "Subject: $subject\r\n\r\n";
  540.     print S "$message";
  541.     print S "\r\n.\r\n";
  542.  
  543.     $_ = <S>;
  544.  
  545.     if (/^[45]/)
  546.     {
  547.         close(S);
  548.         return(-7);
  549.     }
  550.  
  551.     print S "quit\r\n";
  552.     $_ = <S>;
  553.  
  554.     close(S);
  555.     return(1);
  556. }
  557.  
  558. ######################################
  559. # send mail containing the form data
  560. #
  561. sub send_mail
  562. {
  563.     my ($clnt_email, $email_dst, $subject, $message) = @_;    # list assignment
  564.  
  565.     if ( !open(MAIL, "|$mail_program") )
  566.     {
  567.         &print_error_page;
  568.         exit;
  569.     }
  570.     print MAIL <<__END_OF_MAIL__;
  571. To: $email_dst
  572. From: $clnt_email
  573. Subject: $subject
  574.  
  575. $message
  576.  
  577. __END_OF_MAIL__
  578.  
  579.     close (MAIL);
  580. }
  581.  
  582. ######################################
  583. # mail open error message
  584. sub print_error_page
  585. {
  586.     #******************** CUSTOMIZABLE TEXT ********************
  587.     $error_page  = "Content-type: text/html\n\n";
  588.     $error_page .= "<TITLE> System Error </TITLE>";
  589.     $error_page .= "<H2> System Error </H2>";
  590.     $error_page .= "The system is not responding, and the form could not be processed. ";
  591.     $error_page .= "Please try again later.";
  592.     $error_page .= "<P>Thank you for taking the time to fill out the form. ";
  593.     $error_page .= "Sorry for the inconvenience!";
  594.  
  595.     if ( $in{'.back_to_url'} )
  596.     {
  597.         $error_page .= "<P>Return to <A HREF=\"$in{'.back_to_url'}\">$in{'.back_to_url'}</A>";
  598.     }
  599.  
  600.     print $error_page;
  601. }
  602.  
  603. ######################################
  604. # Send an acknowledgement
  605. #
  606. sub send_acknowledgement
  607. {
  608.     # Get address of page that we came from and strip page name
  609.     $ENV{'HTTP_REFERER'} =~ m[(.+/)];
  610.  
  611.     $new_url = $1;
  612.  
  613.     if ( $in{'.thanks_url'} =~ /http:\/\//)
  614.     {
  615.         print "Location: $in{'.thanks_url'}\n\n";
  616.     }
  617.     elsif ( $in{'.thanks_url'} )
  618.     {
  619.         print "Location: $new_url$in{'.thanks_url'}\n\n";
  620.     }
  621.     else
  622.     {
  623.         &send_thanks_page;
  624.     }
  625. }
  626.  
  627. ######################################
  628. # generic acknowledgement page
  629. sub send_thanks_page
  630. {
  631.     #******************** CUSTOMIZABLE TEXT ********************
  632.     $thanks_page  = "Content-type: text/html\n\n";
  633.     $thanks_page .= "<TITLE>Form Acknowledgement</TITLE>";
  634.     $thanks_page .= "<H2>Thank You</H2>";
  635.     $thanks_page .= "Your information has been submitted to ";
  636.     $thanks_page .= "<A HREF=\"mailto:$in{'.email_dest'}\">$in{'.email_dest'}</A>.<p>\n";
  637.     $thanks_page .= "Thank you for taking the time to fill out the form!<br>\n";
  638.     #$thanks_page .= "Perl Version = $] <br>\n";
  639.  
  640.     if ( $in{'.back_to_url'} )
  641.     {
  642.         $thanks_page .= "<P>Return to <A HREF=\"$in{'.back_to_url'}\">$in{'.back_to_url'}</A>";
  643.     }
  644.  
  645.     print $thanks_page;
  646. }